﻿Shader "WSS/Toon/WaterWithDistortion"
{
    Properties
    {
        _Color("Color", Color) = (1, 1, 1, 1)
        _DepthColor("DepthColor", color) = (1,1,1,1)
        _DepthBlend("Depth",float) = 1
        _FoamColor("FoamColor",color) = (1,1,1,1)
        _FoamSpeed("FoamSpeed",float) = 1
        _FoamEdgeDepth("Foam Edge Depth", float) = 1.0
        _WaveSpeed("Wave Speed", float) = 1.0
        _WaveHeight("Wave Height", float) = 0.2
        _NoiseTex("Noise Texture", 2D) = "white" {}
        _MainTex("Main Texture", 2D) = "white" {}
        _DistortStrength("Distort Strength", float) = 1.0
    }

    SubShader
    {
        Tags
        { 
            "Queue" = "Transparent"
        }

        //抓取背景图
        GrabPass
        {
            "_BackgroundTexture"
        }

        Pass
        {
            CGPROGRAM
            #include "UnityCG.cginc"

            #pragma vertex vert
            #pragma fragment frag
            
            float  _FoamEdgeDepth;
            float  _WaveSpeed;
            float  _WaveHeight;
            float _DepthBlend;
            float _FoamSpeed;
            float _DistortStrength;
            float4 _Color;
            float4 _MainTex_ST;
            float4 _DepthColor;
            float4 _FoamColor;
            sampler2D _CameraDepthTexture;
            sampler2D _BackgroundTexture;
            sampler2D _NoiseTex;
            sampler2D _MainTex;

            struct a2v
            {
                float4 vertex : POSITION;
                float4 texCoord : TEXCOORD0;
            };

            struct v2f
            {
                float4 pos : SV_POSITION;
                float2 texCoord : TEXCOORD0;
                float4 screenPos : TEXCOORD1;
                float4 grabPos : TEXCOORD2;
            };

            v2f vert(a2v i)
            {
                v2f o;

                o.pos = UnityObjectToClipPos(i.vertex);

                o.grabPos = ComputeGrabScreenPos(o.pos);

                //波浪顶点动画
                //为什么用tex2Dlod()，见http://www.ufgame.com/9620.html
                float noise = tex2Dlod(_NoiseTex, float4(i.texCoord.xy, 0, 0));
                o.pos.y += sin(_Time*_WaveSpeed*noise+(o.pos.x*o.pos.z*noise))*_WaveHeight;
                //对背景图采样坐标进行噪声扰动
                o.grabPos.y += sin(_Time*_WaveSpeed*noise)*_WaveHeight * _DistortStrength;
                o.grabPos.x += cos(_Time*_WaveSpeed*noise)*_WaveHeight * _DistortStrength;
                // 计算屏幕空间深度
                o.screenPos = ComputeScreenPos(o.pos);
                //水面泡沫位移
                _MainTex_ST.w +=_Time*_FoamSpeed;
                
                o.texCoord = TRANSFORM_TEX(i.texCoord,_MainTex);

                return o;
            }

            float4 frag(v2f i) : COLOR
            {
                //采样并线性化深度值
                float4 depthSample = SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, i.screenPos);
                float depth = LinearEyeDepth(depthSample).r;

                float4 mainColor = tex2D(_MainTex,i.texCoord);
                //通过深度值对比创建边缘泡沫因子,其中i.screenPos.w存放的视空间下的线性深度值
                float foamLine = 1 - saturate(_FoamEdgeDepth * (depth - i.screenPos.w));
                //通过深度值对比创建水体深度颜色渐变因子
                float waterDepth = saturate(_DepthBlend * (depth - i.screenPos.w));
                //采样扰动后的背景图
                float4 backColor = tex2Dproj(_BackgroundTexture, i.grabPos);
                //混合水面水底颜色与边缘泡沫线颜色
                float4 color = lerp(_Color,_DepthColor,waterDepth) + foamLine * _FoamColor;
                //混合背景图与水体颜色以及表面泡沫(MainColor)颜色
                color = lerp(backColor,color,color.a) + mainColor*_FoamColor;

                return color;
            }

            ENDCG
        }
    }
}